package com.gao.weblog.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

import com.gao.weblog.admin.constant.Constants;
import com.gao.weblog.admin.model.vo.dashboard.FindDashboardPVStatisticsInfoRspVO;
import com.gao.weblog.admin.model.vo.dashboard.FindDashboardStatisticsInfoRspVO;
import com.gao.weblog.admin.service.AdminDashboardService;
import com.gao.weblog.common.domain.dos.ArticleDO;
import com.gao.weblog.common.domain.dos.ArticlePublishCountDO;
import com.gao.weblog.common.domain.dos.StatisticsArticlePVDO;
import com.gao.weblog.common.domain.mapper.ArticleMapper;
import com.gao.weblog.common.domain.mapper.CategoryMapper;
import com.gao.weblog.common.domain.mapper.StatisticsArticlePVMapper;
import com.gao.weblog.common.domain.mapper.TagMapper;
import com.gao.weblog.common.utils.Response;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class AdminDashboardServiceImpl implements AdminDashboardService {

    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private StatisticsArticlePVMapper articlePVMapper;

    @Override
    public Response findDashboardStatistics() {
        Long articleTotalCount = articleMapper.selectCount(null);
        Long categoryTotalCount = categoryMapper.selectCount(null);
        Long tagTotalCount = tagMapper.selectCount(null);

        List<ArticleDO> articleDOS = articleMapper.selectAllReadNum();
        Long pvTotalCount = 0L;

        if (CollectionUtils.isNotEmpty(articleDOS)) {
            pvTotalCount = articleDOS.stream().mapToLong(ArticleDO::getReadNum).sum();
        }

        FindDashboardStatisticsInfoRspVO vo = FindDashboardStatisticsInfoRspVO.builder()
                .articleTotalCount(articleTotalCount)
                .categoryTotalCount(categoryTotalCount)
                .tagTotalCount(tagTotalCount)
                .pvTotalCount(pvTotalCount)
                .build();

        return Response.success(vo);
    }

    @Override
    public Response findDashboardPublishArticleStatisics() {
        LocalDate currDate = LocalDate.now();
        LocalDate startDate = currDate.minusYears(1);
        List<ArticlePublishCountDO> articlePublishCountDOS = articleMapper.selectDateArticlePublishCount(startDate, currDate.plusDays(1));

        Map<LocalDate, Long> map = null;

        if (CollectionUtils.isNotEmpty(articlePublishCountDOS)) {
            Map<LocalDate, Long> dateArticleCountMap = articlePublishCountDOS.stream().collect(Collectors.toMap(ArticlePublishCountDO::getDate, ArticlePublishCountDO::getCount));

            map = Maps.newLinkedHashMap();

            for(; startDate.isBefore(currDate) || startDate.isEqual(currDate); startDate=startDate.plusDays(1)){
                Long count = dateArticleCountMap.get(startDate);
                map.put(startDate, Objects.isNull(count) ? 0 : count);
            }
        }

        return Response.success(map);
    }

    @Override
    public Response findDashboardPVStatisics() {
        List<StatisticsArticlePVDO> articlePVDOS = articlePVMapper.selectLatestWeekRecords();
        Map<LocalDate, Long> pvDateCountMap = new HashMap<>();

        if (CollectionUtils.isNotEmpty(articlePVDOS)) {
            pvDateCountMap = articlePVDOS.stream()
                    .collect(Collectors.toMap(StatisticsArticlePVDO::getPvDate, StatisticsArticlePVDO::getPvCount));
        }

        FindDashboardPVStatisticsInfoRspVO vo = null;
        List<String> pvDates = Lists.newArrayList();
        List<Long> pvCounts = Lists.newArrayList();

        LocalDate currDate = LocalDate.now();
        LocalDate tmpDate = currDate.minusWeeks(1);

        for (; tmpDate.isBefore(currDate) || tmpDate.isEqual(currDate); tmpDate=tmpDate.plusDays(1)){
            pvDates.add(tmpDate.format(Constants.MONTH_DAY_FORMATTER));
            Long pvCount = pvDateCountMap.get(tmpDate);
            pvCounts.add(Objects.isNull(pvCount) ? 0 : pvCount);
        }

        vo = FindDashboardPVStatisticsInfoRspVO.builder()
                .pvDates(pvDates)
                .pvCounts(pvCounts)
                .build();

        return Response.success(vo);
    }
}
